package com.mini.vo;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
import org.apache.commons.collections.CollectionUtils;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static com.mini.util.BusinessUtil.*;

/**
 * @author anjl
 * @title BusinessStudentInfo
 * @date 2019/10/2711:28
 */
@Data
@FieldNameConstants
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MemberDataVO implements Serializable {

    @ApiModelProperty(value = "前端使用的唯一id")
    private String unionId = UUID.randomUUID().toString();

    private static final long serialVersionUID = 3856530160651890746L;
    @ApiModelProperty(value = "专员id")
    private Integer teacherId;

    @ApiModelProperty(value = "专员名称")
    private String teacherName;

    @ApiModelProperty(value = "组id")
    private Integer groupId;

    @ApiModelProperty(value = "组织名称")
    private String deptName;

    @ApiModelProperty(value = "加微数")
    private Integer wechatCount;

    @ApiModelProperty(value = "订单数")
    private Integer orderCount;

    @ApiModelProperty(value = "加群数")
    private Integer groupCount;

    @ApiModelProperty(value = "入学测试数")
    private Integer testCount;

    @ApiModelProperty(value = "本周报名单数")
    private Integer thisWeekApplyCount;

    @ApiModelProperty(value = "跨期报名单数")
    private Integer otherWeekApplyCount;

    @ApiModelProperty(value = "总花费")
    private Float totalCost;

    @ApiModelProperty(value = "小课收入")
    private Float miniIncome;

    @ApiModelProperty(value = "推广费用")
    private Float salesCost;

    @ApiModelProperty(value = "本周流水")
    private Float thisWeekFlow;

    @ApiModelProperty(value = "跨期流水")
    private Float otherWeekFlow;

    @ApiModelProperty(value = "退费单数")
    private Integer refundCount;

    @ApiModelProperty(value = "退费金额")
    private Float refundAmount;

    @ApiModelProperty(value = "总报名单数")
    private Integer applyCount;

    @ApiModelProperty(value = "总流水")
    private Float totalFlow;

    @ApiModelProperty(value = "arpu")
    private Double arpu;

    @ApiModelProperty(value = "rpa")
    private Double rpa;

    @ApiModelProperty(value = "cpa")
    private Double cpa;

    @ApiModelProperty(value = "订单成本")
    private Double orderCost;

    @ApiModelProperty(value = "销转")
    private Double salesConvert;

    @ApiModelProperty(value = "加微率")
    private Double wechatPercent;

    @ApiModelProperty(value = "加群率")
    private Double groupPercent;

    @ApiModelProperty(value = "入学测试率")
    private Double testPercent;

    @ApiModelProperty(value = "ROI")
    private Double roi;

    @ApiModelProperty(value = "DROI")
    private Double droi;




    @ApiModelProperty(value ="总花费格式化")
    private String totalCostFmt;

    @ApiModelProperty(value ="小课收入格式化")
    private String miniIncomeFmt;

    @ApiModelProperty(value ="推广费用格式化")
    private String salesCostFmt;

    @ApiModelProperty(value ="本周流水格式化")
    private String thisWeekFlowFmt;

    @ApiModelProperty(value ="跨期流水格式化")
    private String otherWeekFlowFmt;

    @ApiModelProperty(value ="退费金额格式化")
    private String refundAmountFmt;

    @ApiModelProperty(value ="总流水格式化")
    private String totalFlowFmt;

    @ApiModelProperty(value ="arpu格式化")
    private String arpuFmt;

    @ApiModelProperty(value ="rpa格式化")
    private String rpaFmt;

    @ApiModelProperty(value ="cpa格式化")
    private String cpaFmt;

    @ApiModelProperty(value ="订单成本格式化")
    private String orderCostFmt;

    @ApiModelProperty(value ="销转格式化")
    private String salesConvertFmt;

    @ApiModelProperty(value ="加微率格式化")
    private String wechatPercentFmt;

    @ApiModelProperty(value ="加群率格式化")
    private String groupPercentFmt;

    @ApiModelProperty(value ="入学测试率格式化")
    private String testPercentFmt;

    @ApiModelProperty(value ="ROI格式化")
    private String roiFmt;

    @ApiModelProperty(value ="DROI格式化")
    private String droiFmt;


    private List<MemberDataVO> children;

    public void fillData() {
        this.unionId = UUID.randomUUID().toString();

        this.applyCount = getThisWeekApplyCount() + getOtherWeekApplyCount();
        this.totalFlow = getThisWeekFlow() + getOtherWeekFlow();
        this.arpu = division(getTotalFlow(),getApplyCount());
        this.rpa = division(getTotalFlow(),getWechatCount());
        this.cpa = division(getSalesCost(),getWechatCount());
        this.orderCost = division(getSalesCost(),getOrderCount());
        this.salesConvert = division(getApplyCount(),getOrderCount());
        this.wechatPercent = division(getWechatCount(),getOrderCount());
        this.groupPercent = division(getGroupCount(),getOrderCount());
        this.testPercent = division(getTestCount(),getOrderCount());
        this.roi = division(getSalesCost(),getTotalFlow());
        this.droi = division(getSalesCost(),getThisWeekFlow());


        this.totalCostFmt = divisionResultNormal(this.totalCost);
        this.miniIncomeFmt = divisionResultNormal(this.miniIncome);
        this.salesCostFmt = divisionResultNormal(this.salesCost);
        this.thisWeekFlowFmt = divisionResultNormal(this.thisWeekFlow);
        this.otherWeekFlowFmt = divisionResultNormal(this.otherWeekFlow);
        this.refundAmountFmt = divisionResultNormal(this.refundAmount);
        this.totalFlowFmt = divisionResultNormal(this.totalFlow);
        this.arpuFmt = divisionResultNormal(this.arpu);
        this.rpaFmt = divisionResultNormal(this.rpa);
        this.cpaFmt = divisionResultNormal(this.cpa);
        this.orderCostFmt = divisionResultNormal(this.orderCost);
        this.salesConvertFmt = divisionResultPercent(this.salesConvert);
        this.wechatPercentFmt = divisionResultPercent(this.wechatPercent);
        this.groupPercentFmt = divisionResultPercent(this.groupPercent);
        this.testPercentFmt = divisionResultPercent(this.testPercent);
        this.roiFmt = divisionResultPercent(this.roi);
        this.droiFmt = divisionResultPercent(this.droi);
    }


    /**
     * 统计求和
     */
    public static MemberDataVO totalSummary(List<MemberDataVO> collect) {
        return CollectionUtils.isEmpty(collect) ? null : MemberDataVO.builder()
                .refundAmount(collect.stream().map(MemberDataVO::getRefundAmount).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .refundCount(collect.stream().map(MemberDataVO::getRefundCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .otherWeekFlow(collect.stream().map(MemberDataVO::getOtherWeekFlow).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .thisWeekFlow(collect.stream().map(MemberDataVO::getThisWeekFlow).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .salesCost(collect.stream().map(MemberDataVO::getSalesCost).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .miniIncome(collect.stream().map(MemberDataVO::getMiniIncome).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .totalCost(collect.stream().map(MemberDataVO::getTotalCost).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .thisWeekApplyCount(collect.stream().map(MemberDataVO::getThisWeekApplyCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .otherWeekApplyCount(collect.stream().map(MemberDataVO::getOtherWeekApplyCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .groupCount(collect.stream().map(MemberDataVO::getGroupCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .testCount(collect.stream().map(MemberDataVO::getTestCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .wechatCount(collect.stream().map(MemberDataVO::getWechatCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .orderCount(collect.stream().map(MemberDataVO::getOrderCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(null))
                .build();
    }

}
